package service

import (
	"errors"
	"github.com/spf13/viper"
	"go-shop-admin/pkg/e"
	"go-shop-admin/pkg/serializer"
	"go-shop-admin/pkg/zydhfile"
	"go-shop-admin/pkg/zydhlog"
	"math/rand"
	"mime/multipart"
	"path"
	"strconv"
	"strings"
	"time"
)

//文件上传

// 设置文件上传大小
var maxMultipartMemory = int64(8 << 20)

// UploadFileVO 返回的格式
type UploadFileVO struct {
	FilePath []string `json:"filepath"`
}

// BuildUploadFile 序列化
func BuildUploadFile(filepath []string) *UploadFileVO {
	return &UploadFileVO{
		FilePath: filepath,
	}
}

// UploadFile 上传文件 单文件和多文件上传
func UploadFile(savePath string, form *multipart.Form) *serializer.Response {
	//多文件
	files := form.File["file"]

	//检查文件
	fileNum, err := checkFile(files)
	if err != nil {
		return serializer.NewResponse(e.ErrorUploadFile, e.TipsNil, err.Error(), nil)
	}

	//获取文件应该上传的路径 "/images/avatar/" 默认 "/file/" 也可以是给每个用户根据id见一个文件夹
	saveDir, err := setUploadFilePath(savePath)
	if err != nil {
		return serializer.NewResponse(e.ErrorCreateUploadFileDir, err.Error(), e.TipsErrorUploadFile, nil)
	}

	paths := make([]string, fileNum)
	//上传文件
	for k, file := range files {
		//设置上传文件的名称
		filename := setUploadFilename(file.Filename, 0)
		dse := path.Join(saveDir + filename)

		//判断文件是否存在
		if zydhfile.FileOrDirPathIsExist(dse) {
			paths[k] = dse
			continue
		}

		// 上传文件到指定的目录  //将读到的文件保存到本地(服务端)
		if err = zydhfile.SaveFile(file, "."+dse); err != nil {
			return serializer.NewResponse(e.ErrorFailUploadFile, err.Error(), e.TipsErrorUploadFile, nil)
		}
		paths[k] = dse
	}
	//返回token和用户信息
	return serializer.NewResponse(e.Success, e.TipsOk, e.TipsSuccessOperate, BuildUploadFile(paths))
}

// 检查文件
func checkFile(files []*multipart.FileHeader) (fileNum int, err error) {
	//判断文件的大小是否超出
	isOverSize := false
	overSizeFilename := ""
	for _, file := range files {
		if file.Size > maxMultipartMemory {
			isOverSize = true
			overSizeFilename = file.Filename
			break
		}
		fileNum++
	}
	if fileNum == 0 {
		return 0, errors.New(e.TipsErrorUploadFileNotNil)
	}
	if isOverSize {
		return 0, errors.New(overSizeFilename + e.TipsErrorUploadFileOverMax + "8m")
	}
	return fileNum, nil
}

// setUploadFilePath 设置上传文件的路径和文件名
// param string savePath 指定存放的文件目录
// return dst string  /website/images/avatar/
func setUploadFilePath(savePath string) (dst string, err error) {
	//文件存放路径
	if savePath == "" {
		savePath = "/file/"
	}

	rootPath := getUploadFilePath(savePath)
	//判断文件路径是否存在，不存在创建
	if !zydhfile.FileOrDirPathIsExist(rootPath) {
		if ok, errs := zydhfile.MkdirAll("."+rootPath, zydhfile.DefaultPerm); !ok {
			zydhlog.Error(errs.Error())
			return "", errors.New(rootPath + "创建目录失败，err:" + errs.Error())
		}
	}
	return rootPath, nil
}

// 设置上传文件的名称
// param string filename 文件名
// param scene int 场景 0 不更改文件名 1 更改文件名
// return string  avatar.jpg
func setUploadFilename(filename string, scene int) string {
	//更改文件的名称
	if scene == 1 {
		filename = encryptFileName(filename)
	}
	return filename
}

// 获取文件存放路径
func getUploadFilePath(path string) string {
	//return conf.AppConf.PathConf.UploadFilePath + path + time.Now().Format("20060102") + "/"
	return viper.Get("path.upload_file_path").(string) + path + time.Now().Format("20060102") + "/"
}

// 更改图片名称
func encryptFileName(filename string) string {
	//加密图片   file.Filename  QQ图片20220529094630.png
	return time.Now().Format("200601021504050006") + strconv.Itoa(rand.Intn(1000)) + "." + strings.Split(filename, ".")[1]
	//                               20220529104657002281.png
}
